#ifndef MODBUS_MASTER_H
#define MODBUS_MASTER_H

#include "stdint.h"

#define USE_RTX 0

#if   USE_RTX 

#define MUTE_BUS_LOCK		1
#define MUTE_BUS_UNLOCK		0


// Modbus功能码定义
#define MODBUS_FC_READ_COILS        0x01
#define MODBUS_FC_READ_DISCRETE     0x02
#define MODBUS_FC_READ_HOLDING      0x03
#define MODBUS_FC_READ_INPUT        0x04
#define MODBUS_FC_WRITE_SINGLE  	0x06  // 写单个保持寄存器
#define MODBUS_FC_WRITE_MULTIPLE	0x10 // 写多个保持寄存器

// 配置参数
#define MODBUS_MAX_DATA_LEN         256
#define MODBUS_ENABLE_RETRY         1   // 1-启用重传，0-禁用
#define MODBUS_MAX_RETRY_COUNT      3   // 最大重传次数


// 请求状态
typedef enum {
    MODBUS_STATUS_IDLE,
    MODBUS_STATUS_SENDING,
    MODBUS_STATUS_WAITING,
    MODBUS_STATUS_COMPLETE,
    MODBUS_STATUS_TIMEOUT,
    MODBUS_STATUS_ERROR
} ModbusStatus_t;

// Modbus请求结构体
typedef struct {
    uint8_t slave_addr;           // 从站地址
    uint8_t function_code;        // 功能码
    uint16_t start_addr;          // 起始地址
    uint16_t data_len;            // 数据长度/数量
    uint8_t *data;                // 数据缓冲区(用于写操作)
    uint32_t timeout;             // 超时时间(ms)
    ModbusStatus_t status;        // 请求状态
    uint8_t retry_count;          // 重传计数器
    void (*callback)(void *);     // 回调函数
} ModbusRequest_t;

// Modbus主站上下文
typedef struct {
    ModbusRequest_t current_req;   // 当前请求
    osMessageQueueId_t req_queue;  // 请求队列
	bool bus_lock;          		// 总线锁(互斥锁)
    osTimerId_t timeout_timer;     // 超时定时器
	
	void (*Master_send)(uint8_t* tx_buffer, uint16_t tx_len);     // 回调函数
    uint8_t rx_buffer[MODBUS_MAX_DATA_LEN + 4]; // 接收缓冲区
    uint16_t rx_index;             // 接收缓冲区索引
} ModbusMaster_t;


// 函数声明
uint8_t ModbusMaster_Init(ModbusMaster_t *master, void (*Master_send)(uint8_t* tx_buffer, uint16_t tx_len));

/* 读线圈 */
uint8_t ModbusMaster_ReadCoils(ModbusMaster_t *master, uint8_t slave_addr, 
                             uint16_t start_addr, uint16_t count, 
                             uint32_t timeout, void (*callback)(void *));
/* 读保存寄存器 */
uint8_t ModbusMaster_ReadHoldingRegisters(ModbusMaster_t *master, uint8_t slave_addr, 
                                        uint16_t start_addr, uint16_t count, 
                                        uint32_t timeout, void (*callback)(void *));
/* 写单字节保持寄存器 */
uint8_t ModbusMaster_WriteSingleRegister(ModbusMaster_t *master, uint8_t slave_addr, 
                                       uint16_t reg_addr, uint16_t value, 
                                       uint32_t timeout, void (*callback)(void *));
/* 写多个字节保持寄存器 */
uint8_t ModbusMaster_WriteMultipleRegisters(ModbusMaster_t *master, uint8_t slave_addr, 
                                          uint16_t start_addr, uint16_t count, 
                                          uint16_t *values, uint32_t timeout, 
                                          void (*callback)(void *)) ;


/* 发送并接收处理任务 */
void Task_Modbus_SendAndRecv(void *argument); 
/* 响应回复 超时回调 */
void Modbus_ResponseTimeout_Callback(void *argument);

/* 接收回复数据，在usart接收中断调用 */
void Modbus_RTU_RecvTask(ModbusMaster_t*master, uint8_t data);

/*回复数据接收超时，认为接收完成 */
void Modbus_Recv_Timeout(ModbusMaster_t*master);


/*
	报文的地址、功能码检查
	return 1 = fail， 0 = success
*/
uint8_t ModbusMaster_addr_code_check(uint8_t *raw_data, uint8_t *slave_addr, uint8_t *function_code);
/*
	接收报文的CRC校验
	return 1 = fail， 0 = success
*/
uint8_t ModbusMaster_CRC_check(uint8_t *raw_data, uint16_t data_len);


#endif

#endif // MODBUS_MASTER_H
    